from django.shortcuts import render

# Create your views here.
from rest_framework.decorators import (
    api_view,
    authentication_classes,
    permission_classes,
)
from rest_framework.response import Response
from rest_framework import status
from .models import McOrder
from .serializers import McServiceSerializer
from app.common.pagination import StandardResultsSetPagination
from rest_framework.permissions import IsAuthenticated


# ===== 微信商户配置 =====
APP_ID = "wx1234567890abcdef"               # 小程序 AppID
MCH_ID = "1600000000"                       # 商户号
MCH_KEY = "your_v3_api_key"                 # APIv3 密钥
MCH_CERT_SERIAL = "3A2B4C5D6E7F1234567890"  # 商户证书序列号
PRIVATE_KEY_PATH = "/srv/certs/apiclient_key.pem"
NOTIFY_URL = "https://api.yourdomain.com/api/order/wechat/notify"
UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"


# ====== 微信支付配置 ======
WECHAT_V3_KEY = "your_v3_api_key_32chars"  # 必须是32位的APIv3密钥


# ===== 加载私钥签名工具 =====
def load_private_key():
    with open(PRIVATE_KEY_PATH, "rb") as f:
        return serialization.load_pem_private_key(f.read(), password=None)

def sign_message(message: str) -> str:
    private_key = load_private_key()
    signature = private_key.sign(
        message.encode("utf-8"),
        padding.PKCS1v15(),
        hashes.SHA256(),
    )
    return base64.b64encode(signature).decode("utf-8")


def decrypt_resource(resource):
    """解密微信支付回调中的 resource"""
    nonce = resource["nonce"]
    ciphertext = resource["ciphertext"]
    associated_data = resource["associated_data"]

    aes_key = WECHAT_V3_KEY.encode()
    cipher = Cipher(algorithms.AES(aes_key), modes.GCM(nonce.encode()))
    decryptor = cipher.decryptor()
    decryptor.authenticate_additional_data(associated_data.encode())
    plaintext = decryptor.update(base64.b64decode(ciphertext)) + decryptor.finalize()
    return json.loads(plaintext.decode())



@api_view(["GET"])
@permission_classes([IsAuthenticated]) 
def order_list(request):
    items = McOrder.objects.select_related(
        "user", "patient", "service", "companion_gender"
    ).order_by("-created_time")

    # 条件过滤
    user_id = request.GET.get("user_id")
    if user_id:
        items = items.filter(user_id=user_id)

    patient_id = request.GET.get("patient_id")
    if patient_id:
        items = items.filter(patient_id=patient_id)

    service_id = request.GET.get("service_id")
    if service_id:
        items = items.filter(service_id=service_id)

    start_time = request.GET.get("start_time")
    if start_time:
        items = items.filter(start_time=start_time)

    hospital = request.GET.get("hospital")
    if hospital:
        items = items.filter(hospital=hospital)

    hospital = request.GET.get("hospital")
    if hospital:
        items = items.filter(hospital=hospital)

    department = request.GET.get("department")
    if department:
        items = items.filter(department=department)

    companion_gender = request.GET.get("companion_gender")
    if companion_gender:
        items = items.filter(companion_gender=companion_gender)

    service_duration = request.GET.get("service_duration")
    if service_duration:
        items = items.filter(service_duration=service_duration)

    status = request.GET.get("status")
    if status:
        items = items.filter(status=status)

    # 分页
    paginator = StandardResultsSetPagination()
    result_page = paginator.paginate_queryset(items, request)
    serializer = McServiceSerializer(result_page, many=True)

    return paginator.get_paginated_response(serializer.data)


@api_view(["GET"])
@permission_classes([IsAuthenticated]) 
def order_detail(request, pk):
    try:
        item = McOrder.objects.get(pk=pk)
    except McOrder.DoesNotExist:
        return Response({"error": "Not found"}, status=status.HTTP_404_NOT_FOUND)
    serializer = McServiceSerializer(item)
    return Response(serializer.data)


@api_view(["POST"])
@permission_classes([IsAuthenticated]) 
def order_create(request):
    serializer = McServiceSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(["PUT"])
@permission_classes([IsAuthenticated]) 
def order_update(request, pk):
    try:
        item = McOrder.objects.get(pk=pk)
    except McOrder.DoesNotExist:
        return Response({"error": "Not found"}, status=status.HTTP_404_NOT_FOUND)
    serializer = McServiceSerializer(item, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(["DELETE"])
@permission_classes([IsAuthenticated]) 
def order_delete(request, pk):
    try:
        item = McOrder.objects.get(pk=pk)
    except McOrder.DoesNotExist:
        return Response({"error": "Not found"}, status=status.HTTP_404_NOT_FOUND)
    item.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)


@api_view(["POST"])
@permission_classes([IsAuthenticated]) 
def generate_order(request):
    """
    微信支付下单 (JSAPI)
    前端传递：
      {
        "openid": "用户openid",
        "amount": 100,  # 单位分
        "body": "陪诊服务",
        "order_no": "ORDER_20251015xxxx"
      }
    """
    data = request.data
    openid = data.get("openid")
    amount = data.get("amount", 100)
    body = data.get("body", "陪诊服务费用")
    out_trade_no = data.get("order_no")

    # === Step 1. 组装请求体 ===
    payload = {
        "appid": APP_ID,
        "mchid": MCH_ID,
        "description": body,
        "out_trade_no": out_trade_no,
        "notify_url": NOTIFY_URL,
        "amount": {"total": amount, "currency": "CNY"},
        "payer": {"openid": openid},
    }

    # === Step 2. 构建签名头 ===
    http_method = "POST"
    canonical_url = "/v3/pay/transactions/jsapi"
    timestamp = str(int(time.time()))
    nonce_str = str(uuid.uuid4()).replace("-", "")
    body_json = json.dumps(payload)
    message = f"{http_method}\n{canonical_url}\n{timestamp}\n{nonce_str}\n{body_json}\n"
    signature = sign_message(message)

    authorization = (
        f'WECHATPAY2-SHA256-RSA2048 '
        f'mchid="{MCH_ID}",'
        f'nonce_str="{nonce_str}",'
        f'signature="{signature}",'
        f'timestamp="{timestamp}",'
        f'serial_no="{MCH_CERT_SERIAL}"'
    )

    headers = {
        "Content-Type": "application/json",
        "Authorization": authorization,
    }

    # === Step 3. 发起微信下单请求 ===
    res = requests.post(UNIFIED_ORDER_URL, headers=headers, data=body_json)
    result = res.json()

    if res.status_code != 200 or "prepay_id" not in result:
        return JsonResponse({"error": "下单失败", "detail": result}, status=400)

    prepay_id = result["prepay_id"]

    # === Step 4. 二次签名给前端 ===
    pay_time = str(int(time.time()))
    pay_nonce = str(uuid.uuid4()).replace("-", "")
    package = f"prepay_id={prepay_id}"
    sign_str = f"{APP_ID}\n{pay_time}\n{pay_nonce}\n{package}\n"
    pay_sign = sign_message(sign_str)

    # === Step 5. 保存订单（可选） ===
    McOrder.objects.create(
        user_id=data.get("user_id"),
        service_id=data.get("service_id"),
        patient_id=data.get("patient_id"),
        hospital=data.get("hospital"),
        department=data.get("department"),
        amount=amount,
        status=1,  # 待支付
        order_no=out_trade_no,
        start_time=data.get("start_time"),
    )

    # === Step 6. 返回前端参数 ===
    return JsonResponse({
        "timeStamp": pay_time,
        "nonceStr": pay_nonce,
        "package": package,
        "signType": "RSA",
        "paySign": pay_sign,
        "order_no": out_trade_no,
    })



@api_view(["POST"])
@permission_classes([IsAuthenticated]) 
def wechat_notify(request):
    """
    微信支付异步通知回调
    文档：https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_5.shtml
    """
    try:
        data = json.loads(request.body.decode("utf-8"))
        resource = data.get("resource")
        if not resource:
            return JsonResponse({"code": "FAIL", "message": "无效的通知内容"})

        # Step 1: 解密
        result = decrypt_resource(resource)
        out_trade_no = result.get("out_trade_no")
        trade_state = result.get("trade_state")

        # Step 2: 更新订单状态
        try:
            order = McOrder.objects.get(order_no=out_trade_no)
            if trade_state == "SUCCESS":
                order.status = 2  # 已支付
            elif trade_state == "REFUND":
                order.status = 3  # 已退款
            else:
                order.status = 4  # 其他状态
            order.save()
        except McOrder.DoesNotExist:
            print("❌ 未找到订单:", out_trade_no)

        # Step 3: 返回成功响应（必须）
        return JsonResponse({"code": "SUCCESS", "message": "成功"})
    except Exception as e:
        print("⚠️ 支付回调错误:", e)
        return JsonResponse({"code": "FAIL", "message": "系统异常"})